
package com.yang.design.structure.proxy.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 代理工厂-动态生成代理对象
 */
public class ProxyFactory {

    //维护一个目标对象,由于是动态的,所以用Object
    private Object target;

    //构造方法
    public ProxyFactory(Object target) {
        this.target = target;
    }

    /**
     * 为成员变量target(目标类),生成代理类
     * @return
     */
    public Object getProxyInstance(){

        //使用Proxy的静态方法去获取代理对象,注意不要导错包了
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),//目标类的类加载器
                target.getClass().getInterfaces(),//目标类实现的接口,返回数组，接口可以多实现
                new InvocationHandler() {  //事件处理器，匿名内部类
                    /**
                     * invoke方法参数说明
                     * @param proxy 代理对象
                     * @param method  在代理对象中上调用的接口方法Method实例,对应静态代理接口中的save()方法，即要目标类实现的接口方法
                     * @param args 代理对象调用接口方法时传递的实际参数,接口方法返回值
                     * @return: java.lang.Object 返回目标对象方法的返回值,没有返回值就返回null
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("开启事务");
                        //执行目标对象方法,利用反射调用Method对象的invoke方法。入参是第一个是对象，第二是方法参数
                        //所以可以执行目标类的方法
                        Object invoke = method.invoke(target, args);
                        System.out.println("提交事务");
                        return invoke;
                    }
                }
        );
    }
}